package com.rbac.config;

import com.rbac.service.RedisService;
import com.rbac.common.RedisKey;
import com.rbac.util.JwtUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

	private static final Logger logger = LoggerFactory.getLogger(JwtAuthenticationFilter.class);

	@Autowired
	@Lazy
	private JwtUtil jwtUtil;

	@Autowired
	@Lazy
	private UserDetailsService userDetailsService;

	@Autowired
	private RedisService redisService;

	@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {
		
		String requestURI = request.getRequestURI();
		logger.debug("JWT认证过滤器处理请求: {}", requestURI);
		
		try {
			String token = extractTokenFromRequest(request);
			
			if (token != null) {
				logger.debug("从请求中提取到Token");
				// 黑名单校验
				String black = redisService.getString(RedisKey.TOKEN_BLACKLIST, token);
				if (black != null) {
					logger.debug("Token在黑名单中，拒绝认证");
					filterChain.doFilter(request, response);
					return;
				}
				
				if (jwtUtil.validateToken(token, null)) {
					String username = jwtUtil.getUsernameFromToken(token);
					logger.debug("Token验证成功，用户名: {}", username);
					
					if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
						UserDetails userDetails = userDetailsService.loadUserByUsername(username);
						
						if (userDetails != null) {
							UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
								userDetails, null, userDetails.getAuthorities());
							
							SecurityContextHolder.getContext().setAuthentication(authentication);
							logger.debug("用户认证成功，设置SecurityContext: {}", username);
						}
					}
				} else {
					logger.debug("Token验证失败");
				}
			} else {
				logger.debug("请求中没有Token");
			}
		} catch (Exception e) {
			logger.error("JWT认证失败", e);
		}
		
		filterChain.doFilter(request, response);
	}

	private String extractTokenFromRequest(HttpServletRequest request) {
		String bearerToken = request.getHeader("Authorization");
		if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
			return bearerToken.substring(7);
		}
		return null;
	}
} 